import { loadWorker } from "./workerLoader";
import { generateUUID } from "./uuid";

async function doInWorker(name, params, transfer=undefined){
  /** @type {Worker} */
  let worker = await loadWorker("workerMonoHmsb.js"); // generated file, see webpack.config.js
  return new Promise((resolve) => {
    let uuid = generateUUID();
    let listener = (event) => {
      let data = event.data;
      if (data.uuid === uuid){
        worker.removeEventListener("message", listener);
        resolve(data);
      }
    };
    worker.addEventListener("message", listener);
    let data = {
      function: name,
      uuid,
      ...params
    };
    worker.postMessage(data, transfer);
  });
}

/**
 * micropython MONO_HLSB to ImageDataArray, using WASM
 * @param {Uint8Array} data 
 * @param {number} imgWidth 
 * @param {number} imgHeight 
 * @param {number} [scale=1]
 * @param {[number,number,number]} [color=[0,0,0]]
 * @param {[number,number,number]} [backgroundColor=[-1,-1,-1]]
 * @returns {Promise<Uint8Array>}
 */
export async function drawCanvasDataInWorker(data, imgWidth, imgHeight, scale=1, color=[0x00,0x00,0x00], backgroundColor=[-1,-1,-1]){
  let res = await doInWorker("drawCanvasData",{data, imgWidth, imgHeight, scale, color, backgroundColor});
  return res.return;
}

/**
 * parse MONO_HLSB data from canvas image data
 * @param {Uint8Array} data 
 * @param {number} imgWidth 
 * @param {number} imgHeight 
 * @param {number} scale scale
 * @param {[number,number,number]} color color which is 1
 * @returns {Promise<Uint8Array>}
 */
export async function parseDataFromCanvasInWorker(data, imgWidth, imgHeight, scale=1, color=[0x00,0x00,0x00]){
  let res = await doInWorker("parseDataFromCanvas",{data, imgWidth, imgHeight, scale, color});
  return res.return;
}

/**
 * convert canvas image data to gray scale image
 * @param {Uint8Array} data 
 * @returns {Promise<Uint8Array>}
 */
export async function convertToGrayScaleInWorker(data){
  let res = await doInWorker("convertToGrayScale",{data});
  return res.return;
}

/**
 * convert canvas image data to black and white image
 * @param {Uint8Array} data 
 * @param {number} grayThreshold should be in [0,255]
 * @returns {Promise<Uint8Array>}
 */
export async function convertToBlackWhiteInWorker(data, grayThreshold=127){
  let res = await doInWorker("convertToBlackWhite",{data, grayThreshold});
  return res.return;
}

/**
 * convert canvas image data to black and white image
 * @param {Uint8Array} data 
 * @param {number} imgWidth 
 * @returns {Promise<Uint8Array>}
 */
export async function convertToBlackWhiteDitherInWorker(data, imgWidth){
    let res = await doInWorker("convertToBlackWhiteDither",{data, imgWidth});
    return res.return;
}

/**
 * convert canvas image data to black and white image
 * @param {Uint8Array} data 
 * @param {number} imgWidth 
 * @returns {Promise<Uint8Array>}
 */
export async function convertToBlackWhiteFloydSteinbergInWorker(data, imgWidth){
    let res = await doInWorker("convertToBlackWhiteFloydSteinberg",{data, imgWidth});
    return res.return;
}

export default {
  drawCanvasDataInWorker,
  parseDataFromCanvasInWorker,
  convertToGrayScaleInWorker,
  convertToBlackWhiteInWorker,
  convertToBlackWhiteDitherInWorker,
  convertToBlackWhiteFloydSteinbergInWorker,
}